package net.portly.cst.loader;

import java.util.HashMap;
import java.util.Map;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import net.portly.cst.CSTDocument;
import net.portly.cst.StructuralAssetInstance;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class SimpleLoader implements AssetLoader {

	private Map<String, String> metaData;
	protected String pattern = null;
	protected XPath xpath;
	protected XPathFactory xPathfactory;
	protected Document doc = null;
	
	public SimpleLoader() {
		this.metaData = new HashMap<String, String>();
	}

	/* (non-Javadoc)
	 * @see net.portly.cst.loader.AssetLoader#loadAttributes(net.portly.cst.CSTDocument)
	 */
	public void loadAttributes(CSTDocument cstDoc) {
		this.doc = cstDoc.getDoc();
		NodeList metaNodes = findMetaNodesInDocument();
		applyMetaAttributes(metaNodes);
	}
	
	protected void applyMetaAttributes(NodeList nl) {
		if (nl != null && nl.getLength() > 0 && nl.item(0).getFirstChild() != null) {
			for (int counter = 0; counter < nl.getLength(); counter++) {
				Node nlItem = nl.item(counter);
				if (nlItem != null && nlItem.getNodeType() == Node.ELEMENT_NODE) {
					String content = nlItem.getTextContent();
					metaDataFilter(nlItem, content);
				}
			}
		}
	}

	/**
	 * MetaData is really everything that we find from that xpath expression, and not all is required.
	 * @param nodeName
	 * @param content
	 */
	protected void metaDataFilter(Node node, String content) {
		metaData.put(node.getNodeName(), content);
	}

	protected NodeList findMetaNodesInDocument() {
		xPathfactory = XPathFactory.newInstance();
		xpath = xPathfactory.newXPath();
		
		try {
			XPathExpression expr = xpath.compile(pattern);
			
			return (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
		} catch (XPathExpressionException e) {
			e.printStackTrace();
		}
		
		return null;
	}

	/* (non-Javadoc)
	 * @see net.portly.cst.loader.AssetLoader#getMetaData()
	 */
	public Map<String, String> getMetaData() {
		return metaData;
	}

	public StructuralAssetInstance getStructuralAssetInstance() {
		return null;
	}
}